home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / os2 / e33el2.zip / emacs / 19.33 / lisp / nroff-mode.el < prev    next >
Lisp/Scheme  |  1996-01-20  |  10KB  |  271 lines

  1. ;;; nroff-mode.el --- GNU Emacs major mode for editing nroff source
  2.  
  3. ;; Copyright (C) 1985, 1986, 1994, 1995 Free Software Foundation, Inc.
  4.  
  5. ;; Maintainer: FSF
  6. ;; Keywords: wp
  7.  
  8. ;; This file is part of GNU Emacs.
  9.  
  10. ;; GNU Emacs is free software; you can redistribute it and/or modify
  11. ;; it under the terms of the GNU General Public License as published by
  12. ;; the Free Software Foundation; either version 2, or (at your option)
  13. ;; any later version.
  14.  
  15. ;; GNU Emacs is distributed in the hope that it will be useful,
  16. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. ;; GNU General Public License for more details.
  19.  
  20. ;; You should have received a copy of the GNU General Public License
  21. ;; along with GNU Emacs; see the file COPYING.  If not, write to the
  22. ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  23. ;; Boston, MA 02111-1307, USA.
  24.  
  25. ;;; Commentary:
  26.  
  27. ;; This package is a major mode for editing nroff source code.  It knows
  28. ;; about various nroff constructs, ms, mm, and me macros, and will fill
  29. ;; and indent paragraphs properly in their presence.  It also includes
  30. ;; a command to count text lines (excluding nroff constructs), a command
  31. ;; to center a line, and movement commands that know how to skip macros.
  32.  
  33. ;; Paragraph filling and line-counting currently don't respect comments,
  34. ;; as they should.
  35.  
  36. ;;; Code:
  37.  
  38. (defvar nroff-mode-abbrev-table nil
  39.   "Abbrev table used while in nroff mode.")
  40. (define-abbrev-table 'nroff-mode-abbrev-table ())
  41.  
  42. (defvar nroff-mode-map nil
  43.      "Major mode keymap for nroff mode.")
  44. (if (not nroff-mode-map)
  45.     (progn
  46.       (setq nroff-mode-map (make-sparse-keymap))
  47.       (define-key nroff-mode-map "\t"  'tab-to-tab-stop)
  48.       (define-key nroff-mode-map "\es" 'center-line)
  49.       (define-key nroff-mode-map "\e?" 'count-text-lines)
  50.       (define-key nroff-mode-map "\n"  'electric-nroff-newline)
  51.       (define-key nroff-mode-map "\en" 'forward-text-line)
  52.       (define-key nroff-mode-map "\ep" 'backward-text-line)))
  53.  
  54. (defvar nroff-mode-syntax-table nil
  55.   "Syntax table used while in nroff mode.")
  56.  
  57. (defvar nroff-font-lock-keywords
  58.   (list
  59.    ;; Directives are . or ' at start of line, followed by
  60.    ;; optional whitespace, then command (which my be longer than
  61.    ;; 2 characters in groff).  Perhaps the arguments should be
  62.    ;; fontified as well.
  63.    "^[.']\\s-*\\sw+"
  64.    ;; There are numerous groff escapes; the following get things
  65.    ;; like \-, \(em (standard troff) and \f[bar] (groff
  66.    ;; variants).  This won't currently do groff's \A'foo' and
  67.    ;; the like properly.  One might expect it to highlight an escape's
  68.    ;; arguments in common cases, like \f.
  69.    (concat "\\\\"                     ; backslash
  70.          "\\("                        ; followed by various possibilities
  71.          (mapconcat 'identity
  72.                     '("[f*n]*\\[.+]"  ; some groff extensions
  73.                       "(.."           ; two chars after (
  74.                       "[^(\"]"        ; single char escape
  75.                       ) "\\|")
  76.          "\\)")
  77.    )
  78.   "Font-lock highlighting control in nroff-mode.")
  79.  
  80. ;;;###autoload
  81. (defun nroff-mode ()
  82.   "Major mode for editing text intended for nroff to format.
  83. \\{nroff-mode-map}
  84. Turning on Nroff mode runs `text-mode-hook', then `nroff-mode-hook'.
  85. Also, try `nroff-electric-mode', for automatically inserting
  86. closing requests for requests that are used in matched pairs."
  87.   (interactive)
  88.   (kill-all-local-variables)
  89.   (use-local-map nroff-mode-map)
  90.   (setq mode-name "Nroff")
  91.   (setq major-mode 'nroff-mode)
  92.   (if nroff-mode-syntax-table
  93.       ()
  94.     (setq nroff-mode-syntax-table (copy-syntax-table text-mode-syntax-table))
  95.     ;; " isn't given string quote syntax in text-mode but it
  96.     ;; (arguably) should be for use round nroff arguments (with ` and
  97.     ;; ' used otherwise).
  98.     (modify-syntax-entry ?\" "\"  2" nroff-mode-syntax-table)
  99.     ;; Comments are delimited by \" and newline.
  100.     (modify-syntax-entry ?\\ "\\  1" nroff-mode-syntax-table)
  101.     (modify-syntax-entry ?\n ">  1" nroff-mode-syntax-table))
  102.   (set-syntax-table nroff-mode-syntax-table)
  103.   (make-local-variable 'font-lock-defaults)
  104.   (setq font-lock-defaults '(nroff-font-lock-keywords nil t))
  105.   (setq local-abbrev-table nroff-mode-abbrev-table)
  106.   (make-local-variable 'nroff-electric-mode)
  107.   (setq nroff-electric-mode nil)
  108.   (make-local-variable 'outline-regexp)
  109.   (setq outline-regexp "\\.H[ ]+[1-7]+ ")
  110.   (make-local-variable 'outline-level)
  111.   (setq outline-level 'nroff-outline-level)
  112.   ;; now define a bunch of variables for use by commands in this mode
  113.   (make-local-variable 'page-delimiter)
  114.   (setq page-delimiter "^\\.\\(bp\\|SK\\|OP\\)")
  115.   (make-local-variable 'paragraph-start)
  116.   (setq paragraph-start (concat "[.']\\|" paragraph-start))
  117.   (make-local-variable 'paragraph-separate)
  118.   (setq paragraph-separate (concat "[.']\\|" paragraph-separate))
  119.   ;; comment syntax added by mit-erl!gildea 18 Apr 86
  120.   (make-local-variable 'comment-start)
  121.   (setq comment-start "\\\" ")
  122.   (make-local-variable 'comment-start-skip)
  123.   (setq comment-start-skip "\\\\\"[ \t]*")
  124.   (make-local-variable 'comment-column)
  125.   (setq comment-column 24)
  126.   (make-local-variable 'comment-indent-function)
  127.   (setq comment-indent-function 'nroff-comment-indent)
  128.   (run-hooks 'text-mode-hook 'nroff-mode-hook))
  129.  
  130. (defun nroff-outline-level ()
  131.   (save-excursion
  132.     (looking-at outline-regexp)
  133.     (skip-chars-forward ".H ")
  134.     (string-to-int (buffer-substring (point) (+ 1 (point))))))
  135.  
  136. ;;; Compute how much to indent a comment in nroff/troff source.
  137. ;;; By mit-erl!gildea April 86
  138. (defun nroff-comment-indent ()
  139.   "Compute indent for an nroff/troff comment.
  140. Puts a full-stop before comments on a line by themselves."
  141.   (let ((pt (point)))
  142.     (unwind-protect
  143.     (progn
  144.       (skip-chars-backward " \t")
  145.       (if (bolp)
  146.           (progn
  147.         (setq pt (1+ pt))
  148.         (insert ?.)
  149.         1)
  150.         (if (save-excursion
  151.           (backward-char 1)
  152.           (looking-at "^[.']"))
  153.         1
  154.           (max comment-column
  155.            (* 8 (/ (+ (current-column)
  156.                   9) 8)))))) ; add 9 to ensure at least two blanks
  157.       (goto-char pt))))
  158.  
  159. (defun count-text-lines (start end &optional print)
  160.   "Count lines in region, except for nroff request lines.
  161. All lines not starting with a period are counted up.
  162. Interactively, print result in echo area.
  163. Noninteractively, return number of non-request lines from START to END."
  164.   (interactive "r\np")
  165.   (if print
  166.       (message "Region has %d text lines" (count-text-lines start end))
  167.     (save-excursion
  168.       (save-restriction
  169.     (narrow-to-region start end)
  170.     (goto-char (point-min))
  171.     (- (buffer-size) (forward-text-line (buffer-size)))))))
  172.  
  173. (defun forward-text-line (&optional cnt)
  174.   "Go forward one nroff text line, skipping lines of nroff requests.
  175. An argument is a repeat count; if negative, move backward."
  176.   (interactive "p")
  177.   (if (not cnt) (setq cnt 1))
  178.   (while (and (> cnt 0) (not (eobp)))
  179.     (forward-line 1)
  180.     (while (and (not (eobp)) (looking-at "[.']."))
  181.       (forward-line 1))
  182.     (setq cnt (- cnt 1)))
  183.   (while (and (< cnt 0) (not (bobp)))
  184.     (forward-line -1)
  185.     (while (and (not (bobp))
  186.         (looking-at "[.']."))
  187.       (forward-line -1))
  188.     (setq cnt (+ cnt 1)))
  189.   cnt)
  190.  
  191. (defun backward-text-line (&optional cnt)
  192.   "Go backward one nroff text line, skipping lines of nroff requests.
  193. An argument is a repeat count; negative means move forward."
  194.   (interactive "p")
  195.   (forward-text-line (- cnt)))
  196.  
  197. (defconst nroff-brace-table
  198.   '((".(b" . ".)b")
  199.     (".(l" . ".)l")
  200.     (".(q" . ".)q")
  201.     (".(c" . ".)c")
  202.     (".(x" . ".)x")
  203.     (".(z" . ".)z")
  204.     (".(d" . ".)d")
  205.     (".(f" . ".)f")
  206.     (".LG" . ".NL")
  207.     (".SM" . ".NL")
  208.     (".LD" . ".DE")
  209.     (".CD" . ".DE")
  210.     (".BD" . ".DE")
  211.     (".DS" . ".DE")
  212.     (".DF" . ".DE")
  213.     (".FS" . ".FE")
  214.     (".KS" . ".KE")
  215.     (".KF" . ".KE")
  216.     (".LB" . ".LE")
  217.     (".AL" . ".LE")
  218.     (".BL" . ".LE")
  219.     (".DL" . ".LE")
  220.     (".ML" . ".LE")
  221.     (".RL" . ".LE")
  222.     (".VL" . ".LE")
  223.     (".RS"